package Util;

import java.util.Queue;
import java.util.LinkedList;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

public class SafeQueue {
	private Queue<Object> queue_;
	private int waitGetThreadNum_;
	
	
	private Lock lock_;
	private Condition condition_;
	
	public SafeQueue()
	{
		lock_ = new ReentrantLock(false); 
		condition_ = lock_.newCondition();
		queue_ = new LinkedList<Object>();
		waitGetThreadNum_ = 0;
	}
	
	public boolean remove(Object obj)
	{
		boolean ret = false;
		lock_.lock();
		{
			ret = queue_.remove(obj);
		}
		lock_.unlock();
		return ret;
	}
	
	public Object get() throws InterruptedException
	{
		Object ret = null;
		lock_.lock();
		{
			while (queue_.isEmpty())
			{
				waitGetThreadNum_++;
				condition_.await();
				waitGetThreadNum_--;
			}
			ret = queue_.poll();
		}
		lock_.unlock();
		Config.logger.debug("Get Object["+ret.toString()+"] ");
		return ret;
	}
	
	public void put(Object obj)
	{
		lock_.lock();
		{
			queue_.offer(obj);
			if (waitGetThreadNum_>0)
				condition_.signal();
			Config.logger.debug("put Object["+obj.toString()+"] ");
		}
		lock_.unlock();
	}
	
	public Boolean isEmpty()
	{
		return queue_.isEmpty();
	}
	
	public int size()
	{
		return queue_.size();
	}
}
